package controller

import (
	"go_gin_gorm_oceanlearn_study/common"
	"go_gin_gorm_oceanlearn_study/dto"
	"go_gin_gorm_oceanlearn_study/model"
	"go_gin_gorm_oceanlearn_study/response"
	"go_gin_gorm_oceanlearn_study/util"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/postgres"
	"golang.org/x/crypto/bcrypt"
)

// 用户注册
func Register(c *gin.Context) {
	//获取DB实例
	DB := common.GetDB()

	// 获取参数
	var requestUser = model.User{}
	c.Bind(&requestUser)
	name := requestUser.Name 				//name := c.PostForm("name")
	telephone := requestUser.Telephone		// telephone := c.PostForm("telephone")
	password := requestUser.Password       //password := c.PostForm("password")

	//------------------------------------------------------------------------------
	//因为前端传过来的是JSON，这里获取不到了，需要换方式获取前端传过来的参数
	//1、使用map获取请求的参数
	// var requestMap = make(map[string]string)
	// json.NewDecoder(c.Request.Body).Decode(&requestMap)
	//------------------------------------------------------------------------------

	//------------------------------------------------------------------------------
	//2、使用结构体获取请求的参数
	// var requestUser = model.User{}
	// json.NewDecoder(c.Request.Body).Decode(&requestUser)
	//3、使用Bind函数
	// c.Bind(&requestUser)
	//------------------------------------------------------------------------------

	// 数据验证
	if len(telephone) != 11 {
		// c.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "手机号必须为11位"})
		response.Response(c, http.StatusUnprocessableEntity, 422, nil, "手机号必须为11位")
		return
	}
	if len(password) < 6 {
		// c.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "密码不能少于6位"})
		response.Response(c, http.StatusUnprocessableEntity, 422, nil, "密码不能少于6位")
		return
	}
	//如果没有名字，则给一个随机10位字符串
	if len(name) == 0 {
		name = util.RandomString(10)
	}
	log.Println(name, telephone, password)
	//判断手机号是否存在
	if isTelephoneExist(DB, telephone) {
		// c.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "用户已存在"})
		response.Response(c, http.StatusUnprocessableEntity, 422, nil, "用户已存在")
		return
	}
	//创建用户
	// 因为密码不能明文保存，所以加密一下再保存
	hasedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		// c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "msg": "加密错误"})
		response.Response(c, http.StatusInternalServerError, 500, nil, "加密错误")
		return
	}
	newUser := model.User{
		Name:      name,
		Telephone: telephone,
		Password:  string(hasedPassword), //将加密后的密码保存
	}
	DB.Create(&newUser)

	//注册成功则直接登录，不用再次登录
	// 发放token给前端
	token, err := common.ReleaseToken(newUser)
	if err != nil {
		// c.JSON(http.StatusInternalServerError, gin.H{"code":500, "msg":"系统异常，token发放失败"})
		response.Response(c, http.StatusUnprocessableEntity, 500, nil, "系统异常，token发放失败")
		log.Printf("token generate error : %v", err)
		return
	}

	// 返回结果
	// c.JSON(200, gin.H{"code": 200,"data": gin.H{"token":token},"msg": "登陆成功",})
	response.Success(c, gin.H{"token": token}, "注册成功")

	//返回结果
	// c.JSON(200, gin.H{"code": 200,"message": "注册成功",})
	// response.Success(c, nil, "注册成功")
}

// 用户登录
func Login(c *gin.Context){
	//获取DB实例
	DB := common.GetDB()

	// 获取参数
	telephone := c.PostForm("telephone")
	password := c.PostForm("password")

	// 数据验证
	if len(telephone) != 11 {
		// c.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "手机号必须为11位"})
		response.Response(c, http.StatusUnprocessableEntity, 422, nil, "手机号必须为11位")
		return
	}
	if len(password) < 6 {
		// c.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "密码不能少于6位"})
		response.Response(c, http.StatusUnprocessableEntity, 422, nil, "密码不能少于6位")
		return
	}

	// 判断手机号是否存在
	var user model.User
	DB.Where("telephone = ?", telephone).First(&user)
	if user.ID == 0 {
		// c.JSON(http.StatusUnprocessableEntity, gin.H{"code": 422, "msg": "用户不存在"})
		response.Response(c, http.StatusUnprocessableEntity, 422, nil, "用户不存在")
		return
	}

	// 判断密码是否正确（用bcryt的方法来判断）（原密码加密后密码，      用户输入的密码）
	err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
	if err != nil{
		// c.JSON(http.StatusBadRequest, gin.H{"code":400, "msg":"密码错误"})
		response.Fail(c, nil, "密码错误")
		return
	}

	// 发放token给前端
	// token := "11"
	token, err := common.ReleaseToken(user)
	if err != nil {
		// c.JSON(http.StatusInternalServerError, gin.H{"code":500, "msg":"系统异常，token发放失败"})
		response.Response(c, http.StatusUnprocessableEntity, 500, nil, "系统异常，token发放失败")
		log.Printf("token generate error : %v", err)
		return
	}

	// 返回结果
	// c.JSON(200, gin.H{"code": 200,"data": gin.H{"token":token},"msg": "登陆成功",})
	response.Success(c, gin.H{"token": token}, "登陆成功")
}

// 获取用户信息
func Info(c *gin.Context) {
	user, _ := c.Get("user")

	// c.JSON(http.StatusOK, gin.H{"code": 200, "data": gin.H{"user": user}})
	c.JSON(http.StatusOK, gin.H{"code": 200, "data": gin.H{"user": dto.ToUserDto(user.(model.User))}}) //类型转换
}

//查询当前手机号是否已存在
func isTelephoneExist(db *gorm.DB, telephone string)bool{
	var user model.User
	db.Where("telephone = ?", telephone).First(&user)
	if user.ID != 0 {
		return true
	}
	return false
}

